/**
 * WebSocket相关Mixin
 * 提供WebSocket连接和消息处理的公共方法
 */

import { WEBSOCKET_COMMANDS, WEBSOCKET_STATUS } from '@/constants/websocketEvents';
import { performanceUtils } from '@/utils/common';

export const websocketMixin = {
  data() {
    return {
      WEBSOCKET_COMMANDS,
      WEBSOCKET_STATUS,
      websocketStatus: WEBSOCKET_STATUS.DISCONNECTED,
      reconnectAttempts: 0,
      maxReconnectAttempts: 5,
      reconnectTimer: null
    };
  },

  computed: {
    /**
     * WebSocket连接状态
     */
    isWebSocketConnected() {
      return this.websocketStatus === WEBSOCKET_STATUS.CONNECTED;
    },

    /**
     * 是否可以重连
     */
    canReconnect() {
      return this.reconnectAttempts < this.maxReconnectAttempts;
    }
  },

  methods: {
    /**
     * 初始化WebSocket连接
     */
    initWebSocket() {
      try {
        // 导入WebSocket事件中心
        import('@/services/WebSocketEventCenter').then(({ webSocketEventCenter }) => {
          this.webSocketEventCenter = webSocketEventCenter;
          this.websocketStatus = WEBSOCKET_STATUS.CONNECTED;
          this.reconnectAttempts = 0;
          console.log('WebSocket连接已建立');
        }).catch(error => {
          console.error('WebSocket初始化失败:', error);
          this.handleWebSocketError(error);
        });
      } catch (error) {
        console.error('WebSocket初始化异常:', error);
        this.handleWebSocketError(error);
      }
    },

    /**
     * 处理WebSocket错误
     * @param {Error} error 错误对象
     */
    handleWebSocketError(error) {
      this.websocketStatus = WEBSOCKET_STATUS.ERROR;
      console.error('WebSocket错误:', error);
      
      if (this.canReconnect) {
        this.scheduleReconnect();
      } else {
        this.$message?.error('WebSocket连接失败，请刷新页面重试');
      }
    },

    /**
     * 安排重连
     */
    scheduleReconnect() {
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
      }

      const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
      this.websocketStatus = WEBSOCKET_STATUS.RECONNECTING;
      
      this.reconnectTimer = setTimeout(() => {
        this.reconnectAttempts++;
        this.initWebSocket();
      }, delay);
    },

    /**
     * 发送WebSocket消息
     * @param {Object} data 要发送的数据
     * @param {Function} callback 回调函数
     */
    sendWebSocketMessage(data, callback) {
      if (!this.isWebSocketConnected) {
        console.warn('WebSocket未连接，无法发送消息');
        if (callback) callback(new Error('WebSocket未连接'));
        return;
      }

      try {
        // 使用性能计时器
        const endTimer = performanceUtils.startTimer('WebSocket发送');
        
        // 通过事件中心发送消息
        if (this.webSocketEventCenter) {
          this.webSocketEventCenter.sendMessage(data, (result) => {
            endTimer();
            if (callback) callback(null, result);
          });
        } else {
          throw new Error('WebSocket事件中心未初始化');
        }
      } catch (error) {
        console.error('发送WebSocket消息失败:', error);
        if (callback) callback(error);
      }
    },

    /**
     * 处理WebSocket消息
     * @param {Object} message 接收到的消息
     */
    handleWebSocketMessage(message) {
      try {
        const { cmd, data } = message;
        
        // 使用性能计时器
        const endTimer = performanceUtils.startTimer(`WebSocket消息处理-${cmd}`);
        
        switch (cmd) {
          case WEBSOCKET_COMMANDS.SINGLE_CHAT:
            this.handleSingleChatMessage(data);
            break;
          case WEBSOCKET_COMMANDS.GROUP_CHAT:
            this.handleGroupChatMessage(data);
            break;
          case WEBSOCKET_COMMANDS.MESSAGE_RETRACT:
            this.handleMessageRetract(data);
            break;
          case WEBSOCKET_COMMANDS.MESSAGE_READ_SYNC:
            this.handleMessageReadSync(data);
            break;
          case WEBSOCKET_COMMANDS.ONLINE_STATUS:
            this.handleOnlineStatus(data);
            break;
          case WEBSOCKET_COMMANDS.FRIEND_REQUEST:
            this.handleFriendRequest(data);
            break;
          case WEBSOCKET_COMMANDS.FRIEND_ACCEPT:
            this.handleFriendAccept(data);
            break;
          case WEBSOCKET_COMMANDS.VIDEO_CALL:
            this.handleVideoCall(data);
            break;
          case WEBSOCKET_COMMANDS.VOICE_CALL:
            this.handleVoiceCall(data);
            break;
          case WEBSOCKET_COMMANDS.GROUP_DISBAND:
            this.handleGroupDisband(data);
            break;
          case WEBSOCKET_COMMANDS.ANNOUNCEMENT:
            this.handleAnnouncement(data);
            break;
          case WEBSOCKET_COMMANDS.AMOUNT_UPDATE:
            this.handleAmountUpdate(data);
            break;
          case WEBSOCKET_COMMANDS.FORCE_OFFLINE:
            this.handleForceOffline(data);
            break;
          default:
            console.warn('未知的WebSocket命令:', cmd);
        }
        
        endTimer();
      } catch (error) {
        console.error('处理WebSocket消息失败:', error);
      }
    },

    /**
     * 处理单聊消息
     * @param {Object} data 消息数据
     */
    handleSingleChatMessage(data) {
      this.$store.commit('chat/ADD_MESSAGE', {
        chatId: data.receiveId || data.senderId,
        message: this.normalizeMessage(data)
      });
      this.updateUnreadCount(data.receiveId || data.senderId, 1);
      this.triggerAutoScroll();
    },

    /**
     * 处理群聊消息
     * @param {Object} data 消息数据
     */
    handleGroupChatMessage(data) {
      this.$store.commit('chat/ADD_MESSAGE', {
        chatId: data.groupChatId,
        message: this.normalizeMessage(data)
      });
      this.updateUnreadCount(data.groupChatId, 1);
      this.triggerAutoScroll();
    },

    /**
     * 处理消息撤回
     * @param {Object} data 撤回数据
     */
    handleMessageRetract(data) {
      this.$store.commit('chat/RETRACT_MESSAGE', {
        messageId: data.messageId,
        chatId: data.chatId
      });
    },

    /**
     * 处理已读同步
     * @param {Object} data 已读数据
     */
    handleMessageReadSync(data) {
      this.$store.commit('chat/MARK_MESSAGES_READ', {
        chatId: data.chatId,
        messageIds: data.messageIds
      });
    },

    /**
     * 处理在线状态
     * @param {Object} data 状态数据
     */
    handleOnlineStatus(data) {
      this.$store.commit('user/UPDATE_FRIEND_STATUS', {
        friendId: data.userId,
        isOnline: data.isOnline
      });
    },

    /**
     * 处理好友请求
     * @param {Object} data 请求数据
     */
    handleFriendRequest(data) {
      this.$store.commit('friend/ADD_FRIEND_REQUEST', data);
      this.$message?.info('收到新的好友请求');
    },

    /**
     * 处理好友接受
     * @param {Object} data 接受数据
     */
    handleFriendAccept(data) {
      this.$store.commit('friend/ADD_FRIEND', data);
      this.$message?.success('好友请求已通过');
    },

    /**
     * 处理视频通话
     * @param {Object} data 通话数据
     */
    handleVideoCall(data) {
      this.$emit('video-call', data);
    },

    /**
     * 处理语音通话
     * @param {Object} data 通话数据
     */
    handleVoiceCall(data) {
      this.$emit('voice-call', data);
    },

    /**
     * 处理群组解散
     * @param {Object} data 解散数据
     */
    handleGroupDisband(data) {
      this.$store.commit('group/REMOVE_GROUP', data.groupId);
      this.$message?.warning('群组已解散');
    },

    /**
     * 处理系统公告
     * @param {Object} data 公告数据
     */
    handleAnnouncement(data) {
      this.$store.commit('system/ADD_ANNOUNCEMENT', data);
      this.$message?.info('收到系统公告');
    },

    /**
     * 处理金额更新
     * @param {Object} data 金额数据
     */
    handleAmountUpdate(data) {
      this.$store.commit('user/UPDATE_AMOUNT', data.amount);
    },

    /**
     * 处理强制下线
     * @param {Object} data 下线数据
     */
    handleForceOffline(data) {
      this.$message?.error(data.message || '登录状态异常，请重新登录');
      this.$store.dispatch('user/logout');
      this.$router.push('/login');
    },

    /**
     * 标准化消息格式
     * @param {Object} rawMessage 原始消息
     * @returns {Object} 标准化后的消息
     */
    normalizeMessage(rawMessage) {
      return {
        id: rawMessage.id || rawMessage.messageId,
        content: rawMessage.content || '',
        messageType: rawMessage.messageType || 0,
        senderId: rawMessage.senderId,
        receiveId: rawMessage.receiveId,
        groupChatId: rawMessage.groupChatId,
        createTime: rawMessage.createTime || new Date().toISOString(),
        status: rawMessage.status || 'sent',
        isRead: rawMessage.isRead || false,
        isDelivered: rawMessage.isDelivered || false,
        ...rawMessage
      };
    },

    /**
     * 更新未读计数
     * @param {string} chatId 聊天ID
     * @param {number} increment 增量
     */
    updateUnreadCount(chatId, increment = 1) {
      this.$store.commit('chat/UPDATE_UNREAD_COUNT', { chatId, increment });
    },

    /**
     * 触发自动滚动
     */
    triggerAutoScroll() {
      this.$store.commit('chat/SET_SHOULD_SCROLL', true);
    },

    /**
     * 销毁WebSocket连接
     */
    destroyWebSocket() {
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = null;
      }
      
      if (this.webSocketEventCenter) {
        this.webSocketEventCenter.destroy();
        this.webSocketEventCenter = null;
      }
      
      this.websocketStatus = WEBSOCKET_STATUS.DISCONNECTED;
    }
  },

  mounted() {
    this.initWebSocket();
  },

  beforeDestroy() {
    this.destroyWebSocket();
  }
};

export default websocketMixin;
